package classi;

import interfacce.ExamsManager;
import interfacce.RisolutoreEsame;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
import java.util.TimerTask;
import java.util.TreeSet;

import javax.management.timer.Timer;

public class ExamsManagerImpl extends UnicastRemoteObject implements
		ExamsManager {
	
	private TreeSet<Appello> appelliAperti = null;
	private TreeSet<Appello> appelliScaduti = null;
	private TreeSet<Appello> appelliInCorso = null;
	private TreeSet<Appello> appelliTerminati = null;
	private static ExamsManagerImpl emi = null; //SINGLETON
	
	 

	private ExamsManagerImpl() throws RemoteException {
		super();
		this.appelliAperti = new TreeSet<Appello>();
		this.appelliScaduti = new TreeSet<Appello>();
		this.appelliInCorso = new TreeSet<Appello>();
		this.appelliTerminati = new TreeSet<Appello>();
		
	}
	
	public static synchronized ExamsManagerImpl getInstance() throws RemoteException{ //SINGLETON
		if(emi==null){
			try {
				emi = new ExamsManagerImpl();
			} catch (RemoteException e) {
				System.out.println("PROBLEMI EXAMS MANAGER");
				e.printStackTrace();
			}
			return emi ;
		}//if
		return emi;
	}
	
	private Object readResolve()throws RemoteException{ // per risolvere alcuni problemi di serializzazione 
		return getInstance();
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = -4110186707761592726L;

	@Override
	public void apriAppello(Appello appello) throws RemoteException {
		appelliAperti.add(appello);

	}

	@Override
	public void spostaAppello(Appello appello , TreeSet<Appello> listaSorgente , TreeSet<Appello> listaDestinazione )throws RemoteException {	
		if (listaSorgente.contains(appello)){
			listaDestinazione.add(appello);
			listaSorgente.remove(appello); //TODO da testare se funziona , forse non lavoro con lo stesso riferimento
		}
	}

	@Override
	public boolean eliminaAppello(Appello appello, TreeSet<Appello> listaSelezionata) throws RemoteException{
		return listaSelezionata.remove(appello);
	}

	

	@Override
	public void controllaAppelliScaduti() throws RemoteException{
		Date questoIstante = java.util.GregorianCalendar.getInstance().getTime();
		int cont = 0;
		for(Appello a : appelliAperti){
			if(questoIstante.after(a.getDataScadenza())){
				spostaAppello(a, appelliAperti, appelliScaduti);
				cont++;
			}//if
		}//for
		System.out.println("[EXAM MANAGER]Spostati " + cont +" appelli scaduti");

	}

	@Override
	public boolean prenotaAppello(Appello appello, Studente studente)throws RemoteException {
		// TODO DA VERIFICARE SE IL FORMATO DATA DI QUEST ISTANTE E' UGUALE A QUELLO DEGLI ESAMI 
		Date questoIstante = java.util.GregorianCalendar.getInstance().getTime();
		for (Appello tmp : appelliAperti){
			if(tmp.equals(appello)){
				if (studente.getCarriera().contains(tmp)) {//Se l'esame era già stato sostenuto 
					System.out.println("[EXAM MANAGER]Impossibile prenotarsi: esame gia sostenuto");
					return false ;
				}
				else{
					if (questoIstante.before(tmp.getDataScadenza())){ //se ci prenotiamo prima della scandeza
						tmp.getListaPrenotati().add(studente);
						System.out.println("[EXAM MANAGER]Prenotazione effettuata correttamente");
						return true;
					}//if interno
					else{
						System.out.println("[EXAM MANAGER]Impossibile prenotarsi: tempo scaduto");
						return false;
					}//else
				}//else esterno	
			}//if esterno
		}//for
		return false;
	}//metodo 

	@Override
	public RisolutoreEsame sostieniAppello(String nome, Appello appello,Studente s) throws RemoteException {
		return new RisolutoreEsameImpl(appello.getNome(), appello.getTraccia(), s);
	}

	@Override
	public TreeSet<Appello> getAppelliAperti() throws RemoteException {
		return appelliAperti;
	}

	@Override
	public TreeSet<Appello> getAppelliScaduti() throws RemoteException {
		return appelliScaduti;
	}

	@Override
	public TreeSet<Appello> getAppelliInCorso() throws RemoteException {
		return appelliInCorso;
	}

	@Override
	public TreeSet<Appello> getAppelliTerminati() throws RemoteException {
		return appelliTerminati;
	}
	
	 //TODO Da cancellare main
//	public static void main(String[] args) throws ParseException {
//		 Date oggi = GregorianCalendar.getInstance().getTime( );
//		 SimpleDateFormat sdf = new SimpleDateFormat("hh:mm - dd/MM/yyyy");
//		 String  prova = sdf.format(oggi);
//		 System.out.println(prova);
//	}

}
